{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "from matplotlib import pyplot as plt\n",
    "from tensorflow.contrib import layers\n",
    "%matplotlib inline\n",
    "\n",
    "tf.logging.set_verbosity(tf.logging.INFO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n",
      "(55000, 784)\n",
      "(55000,)\n",
      "(5000, 784)\n",
      "(5000,)\n",
      "(10000, 784)\n",
      "(10000,)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets('./');\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "加载数据，可以看到images里面有55000张测试图像，对应55000个lebel， 以及5000个验证图像对应5000个lebel，10000个测试图像，对应10000个label， 每个图像是28*28像素的灰度图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n1tfEdYdWctolT/w14vNvvMEukek58DsT313nN6ddjjv95Phhc/NA6c/IDcux1YOjnQfONnGHN+08\nfLM7Jjvtktu0NPH8f6Q7dbNPfcHEwSUzt9Zc7L7Yxzb8qmtTpypn46aIfYRIk76rTTzwc7sub/bm\nQ5x2NQMr/XIWLpFIMmRzxLpjXvibiReeY+eHO95+s9OuwcOl7/s63AkDAOAJSRgAAE/KzXB0UiU7\n/Dh/SHsTLz7HHfZ6Zqsdwnrv/jNN3PzdsKGuDDu8OLN5R6dOn2PXRqTstksoUr6eXthuIwr/O/H5\nQMn9XDnwD7vkod75c2N6/jov2mv/zQa7Zdbdw3/Lr3m+Fnxuf68aMBwtIiIqxf3zU6FLdMO7h/3P\nDjG2DBuCDsqZt8i26+3WndjPjoE+ducIE3etlOW0Cw5Pf51+uPskDEcXKGfLFhPPGGmndGoscZcJ\n5SyMPBUUreRd+d9PtuuxwClve7jIL1XsuBMGAMATkjAAAJ6QhAEA8CRh54STqrjb1K1+s7GJF3e2\nyxOe2tLSaTfh5pNNnPbtzxGfP/hV+ipbtjt1gyZPNPGodfar+du+PkCnEZPDK9htJsO3xJu60C4r\nyZCiz+Glz7bzuT/sdZc51Z6THd7c0CpiVbmV3KiBU5565Fv5tntmazOn3PoFO9eYE944SnVG2Lnk\nsX2PMnHXepHnmBG72qP8/Lv2rPO7U35DGkRo6Q93wgAAeEISBgDAk4Qajg4OQc9/8jCnLjgE/cTm\nVib+rldbp13yssJ/XX7lte6QdrfKE0y8+SD7fK/WaO+0y9m6rdCvhb86ZfaFJv7ysHedujFdR5n4\nIXGXkkUru5vdVe2gB+w0RLMU9/rVuX2ZiXd95D6Hyv/c8nJt+aX1Itbt1HYZy9sPn+nUVZ8beZoo\nFkuvbWLiH8e7p6V1qRgy8aJ+bn+b3Wt3hNLZkaciUPwyz+rslK/tPjHfdh9u6BT2k9K3PJA7YQAA\nPCEJAwDgSUINR/95ZQcTL+71rFP3yW67yf9357Yzcfay5UV+3X3VI481zttrh7AYfo6PtEH21/j5\n992pgX7VF5p44XNHm7jtf9c67dafbr81ec5Nk5y63jXsoR71UoKnNLgnNrzabLyJe/ZwN47Prsx4\ntIhIcu1aJr7zmncjtnt/h/1We/U3inf4OVzOHLur0jUT+jl1i3vZaax5vd2/KWd/ENiGa9rs+HSu\n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\n4hLFAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x269ad9ae390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,8))\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4,4,idx+1)\n",
    "    plt.axis('off')\n",
    "    plt.title('[{}]'.format(mnist.train.labels[idx]))\n",
    "    plt.imshow(mnist.train.images[idx].reshape(28,28))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义用于训练的网络，首先，定义网络的输入\n",
    "需要分别定义x（图像数据作为输入），y（label，图片真实代表的数字），learning_rate学习率的placeholder\n",
    "\n",
    "为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，x,y 两个placeholder的第一个维度就是batchsize，，因为还没有确定，所以第一个维度留空"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "tf初始化方法：\n",
    "1.  tf.constant_initializer() 常数初始化\n",
    "2.  tf.ones_initializer() 全1初始化\n",
    "3. tf.zeros_initializer() 全0初始化\n",
    "4. tf.random_uniform_initializer() 均匀分布初始化\n",
    "5. tf.random_normal_initializer() 正态分布初始化\n",
    "6. tf.truncated_normal_initializer() 截断正态分布初始化\n",
    "7. tf.uniform_unit_scaling_initializer() 这种方法输入方差是常数\n",
    "8. tf.variance_scaling_initializer() 自适应初始化\n",
    "9. tf.orthogonal_initializer() 生成正交矩阵\n",
    "--------------------- \n",
    "\n",
    "原文：https://blog.csdn.net/dcrmg/article/details/80034075\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = tf.placeholder('float',[None,784])\n",
    "y = tf.placeholder('int64',[None])\n",
    "learning_rate = tf.placeholder('float')\n",
    "\n",
    "def initialize1(name,shape,stddev = 0.1):    \n",
    "    init_uniform = tf.truncated_normal(shape,stddev=0.1) \n",
    "    regularizer = layers.l1_regularizer(scale=0.1)\n",
    "    return tf.get_variable(name,initializer=init_uniform,regularizer=regularizer)\n",
    "\n",
    "\n",
    "\n",
    "def initialize2(name,shape,n):\n",
    "    minV = -np.sqrt((6/n))\n",
    "    maxV = np.sqrt((6/n))\n",
    "    regularizer = layers.l2_regularizer(scale=0.1)\n",
    "    init_uniform = tf.random_uniform_initializer(minval=minV,maxval=maxV, seed=None, dtype=tf.float32)\n",
    "    return tf.get_variable(name,shape,initializer=init_uniform,regularizer=regularizer) \n",
    "# truncated_normal获得正态分布初始化一个shape的值,stddev:正态分布的标准差\n",
    "\n",
    "def initialize3(name,shape,n):\n",
    "    init_uniform = tf.uniform_unit_scaling_initializer()\n",
    "    regularizer = layers.l2_regularizer(scale=0.1)\n",
    "    return tf.get_variable(name,shape,initializer=init_uniform,regularizer=regularizer) \n",
    "\n",
    "\n",
    "initialize0 = initialize1\n",
    "\n",
    "\n",
    "\n",
    "L1_units_count = 500 # 优化A、调整神经元个数\n",
    "\n",
    "W_1 =  initialize0(\"W_1\",[784,L1_units_count],L1_units_count) #tf.Variable(initialize([784,L1_units_count]))\n",
    "b_1 =  initialize0(\"b_1\",[L1_units_count],L1_units_count)      # tf.Variable(initialize([L1_units_count]))\n",
    "\n",
    "\n",
    "logits_1 = tf.matmul(x,W_1) + b_1\n",
    "output_1 = tf.nn.relu(logits_1)\n",
    "\n",
    "\n",
    "L2_units_count = 500\n",
    "\n",
    "# 优化B 增加隐层\n",
    "W_2 = initialize0(\"W_2\",[L1_units_count,L2_units_count],L2_units_count)\n",
    "b_2 = initialize0(\"b_2\",[L2_units_count],L2_units_count)\n",
    "logits_2 = tf.matmul(output_1,W_2) + b_2\n",
    "output_2 = tf.nn.relu(logits_2)\n",
    "\n",
    "L3_units_count = 500\n",
    "# 优化B 增加隐层\n",
    "W_3 = initialize1(\"W_3\",[L2_units_count,L3_units_count],L3_units_count)\n",
    "b_3 = initialize1(\"b_3\",[L3_units_count],L3_units_count)\n",
    "logits_3 = tf.matmul(output_2,W_3) + b_3\n",
    "output_3 = tf.nn.relu(logits_3)\n",
    "\n",
    "Ln_units_count = 10\n",
    "W_n = initialize0(\"W_n\",[L3_units_count,Ln_units_count],Ln_units_count)\n",
    "b_n = initialize0(\"b_n\",[Ln_units_count],Ln_units_count)\n",
    "logits_n = tf.matmul(output_3,W_n) + b_n\n",
    "\n",
    "# L3_units_count = 10\n",
    "# W_3 = initialize2(\"W_3\",[L1_units_count,L3_units_count],L3_units_count)\n",
    "# b_3 = initialize2(\"b_3\",[L3_units_count],L3_units_count)\n",
    "# logits_3 = tf.matmul(output_1,W_3) + b_3\n",
    "\n",
    "logits = logits_n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义loss和用于优化网络的优化器。loss计算是用了sparse_softmax_cross_entropy_with_logits,这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为可以根据需要设定。\n",
    "## 试试看，增大减小学习率，换个优化器再进行训练会发生什么。\n",
    "https://blog.csdn.net/shenxiaoming77/article/details/77169756 各种算法的使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "cross_entropy_loss = tf.reduce_mean(\n",
    "    tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,labels = y))\n",
    "\n",
    "# 定义优化器，使使cross_entropy损失最小化损失最小化, 这里是用的优化过的梯度下降SGD\n",
    "# 它使用一条数据计算梯度，或者 使用batch_size条数据\n",
    "#这个操作每次执行都会前项一次反向一次，对参数进行优化\n",
    "\n",
    "# optimizer = tf.train.AdamOptimizer( # 0.9794\n",
    "# learning_rate=learning_rate).minimize(cross_entropy_loss)\n",
    "\n",
    "# optimizer = tf.train.GradientDescentOptimizer(  \n",
    "# learning_rate=learning_rate).minimize(cross_entropy_loss)\n",
    "\n",
    "optimizer = tf.train.RMSPropOptimizer(  #0.9738\n",
    "learning_rate=learning_rate).minimize(cross_entropy_loss)\n",
    "\n",
    "## ！！！GradientDescentOptimizer是优化器，minimize是这个优化器用的操作\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布， 要想看到概率分布，还需要做一下softmax。\n",
    "\n",
    "将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "pred = tf.nn.softmax(logits)\n",
    "#tf.argmax能给出tensor对象在某一维度上的其数据最大值所在的索引值\n",
    "correct_pred = tf.equal(tf.argmax(pred,1),y)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 32\n",
    "train_step = 4000\n",
    "\n",
    "#saver用于保存或恢复训练的模型\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.881245, the validation accuracy is 0.8166\n",
      "after 200 training steps, the loss is 0.3972, the validation accuracy is 0.9228\n",
      "after 300 training steps, the loss is 0.391102, the validation accuracy is 0.9394\n",
      "after 400 training steps, the loss is 0.407805, the validation accuracy is 0.8974\n",
      "after 500 training steps, the loss is 0.149875, the validation accuracy is 0.9592\n",
      "after 600 training steps, the loss is 0.134803, the validation accuracy is 0.9482\n",
      "after 700 training steps, the loss is 0.300171, the validation accuracy is 0.9534\n",
      "after 800 training steps, the loss is 0.0362164, the validation accuracy is 0.9536\n",
      "after 900 training steps, the loss is 0.0302845, the validation accuracy is 0.959\n",
      "after 1000 training steps, the loss is 0.0110577, the validation accuracy is 0.9612\n",
      "after 1100 training steps, the loss is 0.0865721, the validation accuracy is 0.9686\n",
      "after 1200 training steps, the loss is 0.183793, the validation accuracy is 0.972\n",
      "after 1300 training steps, the loss is 0.0167623, the validation accuracy is 0.9708\n",
      "after 1400 training steps, the loss is 0.0060926, the validation accuracy is 0.9724\n",
      "after 1500 training steps, the loss is 0.0182742, the validation accuracy is 0.9712\n",
      "after 1600 training steps, the loss is 0.0837531, the validation accuracy is 0.9744\n",
      "after 1700 training steps, the loss is 0.0311902, the validation accuracy is 0.9746\n",
      "after 1800 training steps, the loss is 0.0212751, the validation accuracy is 0.975\n",
      "after 1900 training steps, the loss is 0.0288639, the validation accuracy is 0.9744\n",
      "after 2000 training steps, the loss is 0.00293874, the validation accuracy is 0.9788\n",
      "after 2100 training steps, the loss is 0.00360265, the validation accuracy is 0.979\n",
      "after 2200 training steps, the loss is 0.0175379, the validation accuracy is 0.9796\n",
      "after 2300 training steps, the loss is 0.000463692, the validation accuracy is 0.9792\n",
      "after 2400 training steps, the loss is 0.107852, the validation accuracy is 0.9792\n",
      "after 2500 training steps, the loss is 0.00157073, the validation accuracy is 0.9798\n",
      "after 2600 training steps, the loss is 0.00112937, the validation accuracy is 0.9804\n",
      "after 2700 training steps, the loss is 0.00427065, the validation accuracy is 0.9806\n",
      "after 2800 training steps, the loss is 0.205335, the validation accuracy is 0.9796\n",
      "after 2900 training steps, the loss is 0.485801, the validation accuracy is 0.9796\n",
      "after 3000 training steps, the loss is 0.00251102, the validation accuracy is 0.98\n",
      "after 3100 training steps, the loss is 0.00524826, the validation accuracy is 0.9798\n",
      "after 3200 training steps, the loss is 0.00555172, the validation accuracy is 0.9796\n",
      "after 3300 training steps, the loss is 0.0149741, the validation accuracy is 0.9796\n",
      "after 3400 training steps, the loss is 0.419036, the validation accuracy is 0.98\n",
      "after 3500 training steps, the loss is 0.0362693, the validation accuracy is 0.9802\n",
      "after 3600 training steps, the loss is 0.00201568, the validation accuracy is 0.98\n",
      "after 3700 training steps, the loss is 0.316454, the validation accuracy is 0.9802\n",
      "after 3800 training steps, the loss is 0.319884, the validation accuracy is 0.98\n",
      "after 3900 training steps, the loss is 0.127121, the validation accuracy is 0.98\n",
      "the training is finish!\n",
      "the test accuracy is:  0.9765\n"
     ]
    }
   ],
   "source": [
    "lr = 0.001\n",
    "with tf.Session() as sess:\n",
    "  \n",
    "    \n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    \n",
    "    # 定义验证集与测试集\n",
    "    validate_data={\n",
    "        x:mnist.validation.images,\n",
    "        y:mnist.validation.labels,\n",
    "    }\n",
    "    test_data = {x:mnist.test.images,y:mnist.test.labels}\n",
    "    \n",
    "    \n",
    "    for i in range(train_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size=batch_size)\n",
    "        \n",
    "        if i > 1000:\n",
    "            lr = 0.00033\n",
    "        if i > 2000:\n",
    "             lr = 0.00001\n",
    "       \n",
    "        \n",
    "        _,loss = sess.run(\n",
    "            [optimizer, cross_entropy_loss],\n",
    "            feed_dict={\n",
    "                x: xs,\n",
    "                y: ys,\n",
    "                learning_rate:lr\n",
    "            }\n",
    "        )\n",
    "        \n",
    "        # 每100次训练打印一次损失值与验证准确率\n",
    "        if i>0 and i%100 == 0:\n",
    "            validate_accuracy = sess.run(accuracy,feed_dict=validate_data)\n",
    "            print(\n",
    "            \"after %d training steps, the loss is %g, the validation accuracy is %g\"%(\n",
    "            i,loss,validate_accuracy))\n",
    "            \n",
    "            saver.save(sess,'./model.ckpt',global_step=i)\n",
    "    print('the training is finish!')\n",
    "    #最终的测试准确率\n",
    "    acc = sess.run(accuracy,feed_dict=test_data)\n",
    "    print('the test accuracy is: ',acc)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./model.ckpt-3900\n",
      "1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nyH8AlCccp8pLICkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x269afaf53c8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        \n",
    "        final_pred,acc = sess.run(\n",
    "            [pred,accuracy],\n",
    "            feed_dict={\n",
    "                x:mnist.test.images[:16],\n",
    "                y:mnist.test.labels[:16]\n",
    "            }\n",
    "        )\n",
    "        orders = np.argsort(final_pred)\n",
    "        plt.figure(figsize=(8,8))\n",
    "        print(acc)\n",
    "        for idx in range(16):\n",
    "            order = orders[idx,:][-1]\n",
    "            prob = final_pred[idx,:][order]\n",
    "            plt.subplot(4,4,idx+1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}: [{}]-[{:.1f}%]'.format(mnist.test.labels[idx],order,prob*100))\n",
    "            plt.imshow(mnist.test.images[idx].reshape((28,28)))\n",
    "    else:\n",
    "        pass\n",
    "            "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "FirstTrain中的准确率：\n",
    "\n",
    "    after 900 training steps, the loss is 0.108949, the validation accuracy is 0.9546\n",
    "    \n",
    "    the test accuracy is:  0.9501\n",
    "    \n",
    "测试结果：\n",
    "\n",
    "A. 单纯增加L1层神经元个数：提高到500，发现 训练集和 测试集上都有略微的提升 0.9568， 0.9583\n",
    "\n",
    "B. 增加隐层和调整各层神经元个数\n",
    "\n",
    "                      test     validate_accuracy\n",
    "    L1=200，L2 =200 : 0.9486,   0.9533           倒不如A了 为啥？ \n",
    "    L1=500, L2 =300 : 0.9576    0.9632           \n",
    "    \n",
    "C.修改初始化⽅式\n",
    "\n",
    "                       0.9612    0.9716       (L1\\L2\\L3各500个神经元，3000次训练，l2正则，initialize3) \n",
    "                                             \n",
    "                       0.9732    0.9736        initialize1\n",
    "                       \n",
    "                                 0.9746        0.1学习率\n",
    "                                 \n",
    "                                 0.9794       动态调整学习率, AdamOptimizer\n",
    "                                 \n",
    "                                 0.98         动态调整学习率, RMSPropOptimizer\n",
    "                                 \n",
    "                                 \n",
    "1. 如何修改隐层数量，修改后会起到什么样的效果10分。 \n",
    "    \n",
    "    修改隐层数量请看In[4] 中的内容， 增加隐层只需要在生成一套W和B，然后把上一层的输出作为这一层的输入，这一层的输出，经过激活logits 后，传入到下一层就行了\n",
    "    \n",
    "    增加隐层后，某型能更精准的学习数据，从开始只有一层，到后来我增加到了3层，准确率大概从 95%左右 升到 97%左右， 但是再增加感觉没有多大意义了，因为就这个案例来说拖后腿的地方在别处\n",
    "    \n",
    "2. 如何神经元个数，起到了什么样的效果10分。 \n",
    "    调整神经元个数只要修改 Ln_units_count 这样的值就可以了，修改它导致后面定义W_n b_n的时候传入的shape不同，达到修改神经元个数的目的。 \n",
    "    神经元个数从之前的100增加到了500 ，能够使模型准确率更高一点，但是这个例子中只提高了0.5%左右。\n",
    "\n",
    "3. 如何在模型中添加L1/L2正则化，正则化起什么作⽤10分。\n",
    "    这个我是通过\n",
    "    \n",
    "    def initialize1(name,shape,stddev = 0.1):    \n",
    "        init_uniform = tf.truncated_normal(shape,stddev=0.1) \n",
    "        regularizer = layers.l1_regularizer(scale=0.1)\n",
    "        return tf.get_variable(name,initializer=init_uniform,regularizer=regularizer)\n",
    "    \n",
    "    这个方法增加的正则项，这里使用了L1正则，增加正则项的目的是使模型不要过拟合，过拟合的话，测试集上的得分不能提高，即使训练集能够拟合的非常好。\n",
    "    \n",
    "4. 使⽤不同的初始化⽅式对模型有什么影响10分。\n",
    "\n",
    "    通过调整各种参数，大概有点感觉：\n",
    "        a.增加 模型的隐层数量和 每一层的神经元个数 能够有效提升准确率，但是如果这两项过度增加，产生的影响就不大了，反而会增加计算负担。\n",
    "        b.如果训练集上得分高，测试集得分低，则说明要加一些正则了\n",
    "        c.增加模型训练次数，在模型欠拟合的时候能显著提高准确率，但是如果模型本身不行，增加次数也没有用了，准确率会在一个值附近徘徊。\n",
    "        d.如果模型训练中增长速度太慢，需要考虑提高学习率，或者换一些效率更好的优化算法，比如 RMSprop, AdamOptimizer,Adadelta等等，可以试一试。\n",
    "        e.如果模型到最后的分数上不去了，震荡徘徊，那应该考虑一下动态调整（缩小）学习率，让模型更接近最优值\n",
    "        f.参数初始化部分，好的初始化会让模型更快到达高分位置，但是训练次数足够多的时候，似乎也区别不大，别使用太不合适的初始化值就好。\n",
    "\n",
    "\n",
    "我这次调整采用了如下配置：\n",
    "\n",
    "    隐层数量：3 ，每层500个神经元\n",
    "    \n",
    "    初始化采用： truncated_normal，高斯分拨 stdvv=0.1, 加L1正则项（学习率0.1）\n",
    "    \n",
    "    损失函数采用： 交叉熵损失\n",
    "    \n",
    "    优化器采用：RMSPropOptimizer， 学习率分三级：0.001 0.00033, 0.00001\n",
    "    \n",
    "    \n",
    "    训练次数：4000\n",
    "    \n",
    "    最后结果：\n",
    "    the validation accuracy is 0.98the training is finish!\n",
    "    the test accuracy is:  0.9765\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
